package ezy.lite;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class APKInfo {
    public String appName;
    public Drawable appIcon;
    public String packageName;
    public String versionName;
    public int versionCode;
    public int targetSdkVersion;
    public long size;
    public String path;


    public static APKInfo parse(Context context, File file) {
        if (!file.exists()) {
            return null;
        }
        try {
            Object pkg = getPackage(context, file);
            if (pkg == null) {
                return null;
            }
            Resources res = getResources(context, file);
            if (res == null) {
                return null;
            }

            ApplicationInfo app = (ApplicationInfo)getField(pkg, "applicationInfo");

            APKInfo info = new APKInfo();
            info.versionCode = getIntField(pkg, "mVersionCode");
            info.versionName = (String)getField(pkg, "mVersionName");
            info.packageName = (String)getField(pkg, "packageName");

            info.size = file.length();
            info.path = file.getAbsolutePath();
            info.appName = (app.labelRes == 0) ? file.getName() : (String) res.getText(app.labelRes);
            info.appIcon = (app.icon != 0) ? null : res.getDrawable(app.icon);
            info.targetSdkVersion = app.targetSdkVersion;
            return info;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    private static Resources getResources(Context context, File file) throws Exception {
        // AssetManager asset = new AssetManager();
        // asset.addAssetPath(file.getPath());
        AssetManager asset = (AssetManager)AssetManager.class.newInstance();
        Method addAssetPath = AssetManager.class.getDeclaredMethod("addAssetPath", new Class[] { String.class });
        addAssetPath.invoke(asset, new Object[]{file.getPath()});

        Resources res = context.getResources();
        return new Resources(asset, res.getDisplayMetrics(), res.getConfiguration());
    }

    private static Object getPackage(Context context, File file) throws Exception {
        Class clazz = Class.forName("android.content.pm.PackageParser");
        Constructor ctor = clazz.getConstructor(new Class[]{String.class});
        Method method = clazz.getDeclaredMethod("parsePackage", new Class[]{File.class, String.class, DisplayMetrics.class, Integer.TYPE});

        DisplayMetrics dm = new DisplayMetrics();
        dm.setToDefaults();
        //        PackageParser parser = new PackageParser(uri);
        //        Package pkg = parser.parsePackage(file, uri, dm, 0);
        Object parser = ctor.newInstance(new Object[]{file.getPath()});
        return method.invoke(parser, new Object[] {file, file.getPath(), dm, Integer.valueOf(0)});
    }

    private static Object getField(Object pkg, String field) throws Exception {
        return pkg.getClass().getDeclaredField(field).get(pkg);
    }

    private static int getIntField(Object pkg, String field) throws Exception {
        return pkg.getClass().getDeclaredField(field).getInt(pkg);
    }
}